
#include "BitmapFont.h"
#include "../SGD Wrappers/SGD_String.h"
#include <cassert>


/*************************************************/
// Constructor
BitmapFont::BitmapFont(void)
{
	// Set the data members to 'clean' values
	m_nImageID		= SGD::INVALID_HANDLE;
	
	m_nCharWidth	= 0;
	m_nCharHeight	= 0;
	m_nNumCols		= 0;
	m_nNumRows		= 0;
		
	m_cFirstChar	= 0;
	m_bOnlyUppercase= false;
}

/*************************************************/
// Destructor
BitmapFont::~BitmapFont(void)
{
	SGD::GraphicsManager::GetInstance()->UnloadTexture(m_nImageID);
}


/*************************************************/
// Initialize
//	- setup the font to use the SGD_Font_Glow.png
void BitmapFont::Initialize( void )
{
	m_nImageID		= SGD::GraphicsManager::GetInstance()->LoadTexture(
						L"resource/graphics/Font_Hemi.png" );
	
	m_nCharWidth	= 32;
	m_nCharHeight	= 32;
	m_nNumCols		= 16;
	m_nNumRows		= 16;
		
	m_cFirstChar	= '\0';		// image starts with a space
	m_cFirstChar=1;
	m_bOnlyUppercase= false;
}

/*************************************************/
// Shutdown
//	- unload resources
void BitmapFont::Shutdown( void )
{
	SGD::GraphicsManager::GetInstance()->UnloadTexture( m_nImageID );
	m_nImageID = SGD::INVALID_HANDLE;
}


/*************************************************/
// Draw
//	- draw the text one character at a time
void BitmapFont::Draw(SGD::String * Output, int nX, int nY,
						float fScale, SGD::Color Color) const
{
	// Validate the image
	assert( m_nImageID != SGD::INVALID_HANDLE && "BitmapFont::Draw - image is not set" );


	// Stor5e the starting x position
	int nColStart = nX;

	// Loop through each character in the string
	for(unsigned int i = 0; i < Output->size(); i++ )
	{
		// Get the character out of the string
		wchar_t ch = Output->at(i);


		// Check for whitespace
		if( ch == ' ')
		{
			// Move to the next spot
			nX += (int)((m_nCharHeight - (20* fScale)) * fScale);
			continue;
		}
		else if( ch == '\n')
		{
			// Move to the next row, and reset the x
			nY += (int)(m_nCharHeight * fScale);
			nX =  nColStart;
			continue;
		}
		else if( ch == '\t')
		{
			// Calculate how many characters are already printed
			int diff = (int)((nX - nColStart) / (m_nCharWidth * fScale));

			// Calculate the number of spaces to add to align at every 4 spaces
			int tab  = 4 - (diff % 4);

			nX += (int)(tab * m_nCharWidth * fScale);
			continue;
		}


		// Convert to uppercase?
		if( m_bOnlyUppercase == true )
			ch = toupper( ch );

		

		// Calculate the cell ID for this character
		int id = ch - m_cFirstChar;
		SGD::Rectangle rCell = CellAlgorithm( id );

		if (ch == 'a')
			nX -= int(10 * fScale);
		if (ch == 'A')
			nX -= int(4 * fScale);
		if (ch == 'b')
			nX -= int(10 * fScale);
		if (ch == 'B')
			nX -= int(4 * fScale);
		if (ch == 'c')
			nX -= int(10 * fScale);
		if (ch == 'C')
			nX -= int(8 * fScale);
		if (ch == 'd')
			nX -= int(10 * fScale);
		if (ch == 'e')
			nX -= int(10 * fScale);
		if (ch == 'f')
			nX -= int(10 * fScale);
		if (ch == 'g')
		{
			nX -= int(8 * fScale);
			nY += int(8 * fScale);
		}
		if (ch == 'h')
			nX -= int(8 * fScale);
		if (ch == 'i')
			nX -= int(8 * fScale);
		if (ch == 'j')
		{
			nX -= int(10 * fScale);
			nY += int(6 * fScale);
		}
		if (ch == 'k')
			nX -= int(8 * fScale);
		if (ch == 'l')
			nX -= int(8 * fScale);
		if (ch == 'm')
			nX -= int(10 * fScale);
		if (ch == 'n')
			nX -= int(10 * fScale);
		if (ch == 'o')
			nX -= int(10 * fScale);
		if (ch == 'p')
		{
			nX -= int(8 * fScale);
			nY += int(6 * fScale);
		}
		if (ch == 'q')
		{
			nX -= int(8 * fScale);
			nY += int(6 * fScale);
		}
		if (ch == 'r')
			nX -= int(8 * fScale);
		if (ch == 's')
			nX -= int(8 * fScale);
		if (ch == 't')
			nX -= int(8 * fScale);
		if (ch == 'u')
			nX -= int(8 * fScale);
		if (ch == 'v')
			nX -= int(8 * fScale);
		if (ch == 'w')
			nX -= int(8 * fScale);
		if (ch == 'x')
			nX -= int(8 * fScale);
		if (ch == 'y')
		{
			nX -= int(8 * fScale);
			nY += int(6 * fScale);
		}
		if (ch == 'z')
			nX -= int(8 * fScale);
		if (ch == '!')
			nX -= int(12 * fScale);
	
		

		// Draw the character
		SGD::GraphicsManager::GetInstance()->DrawTextureSection(m_nImageID, { (float)nX, (float)nY }, rCell, 0.0f, {}, Color,{ fScale, fScale }) ;
		//SGD::GraphicsManager::GetInstance()->Draw(
		//	m_nImageID, nX, nY, 
		//	fScale, fScale, &rCell,
		//	0.0f, 0.0f, 0.0f, dwColor );
		if (ch == 'l')
			nX -= int(8 * fScale);
		if (ch == 'f')
			nX -= int(8 * fScale);
		if (ch == 'i')
			nX -= int(12 * fScale);
		if (ch == 'g')
			nY -= int(8 * fScale);
		if (ch == 'j')
		{
			nX -= int(8 * fScale);
			nY -= int(6 * fScale);
		}
		if (ch == 'l')
			nX -= int(4 * fScale);
		if (ch == 'm')
			nX += int(10 * fScale);
		if (ch == 'p')
			nY -= int(6 * fScale);
		if (ch == 'q')
			nY -= int(6 * fScale);
		if (ch == 'r')
			nX -= int(8 * fScale);
		if (ch == 's')
			nX -= int(2 * fScale);
		if (ch == 't')
			nX -= int(10 * fScale);
		if (ch == 'w')
			nX += int(8 * fScale);
		if (ch == 'y')
		{
			nX -= int(2 * fScale);
			nY -= int(6 * fScale);
		}
		if (ch == 'z')
			nX -= int(4 * fScale);


		if (ch == 'E')
			nX += int(4 * fScale);
		if (ch == 'C')
			nX += int(4 * fScale);
		if (ch == 'L')
			nX += int(4 * fScale);
		if (ch == 'G')
			nX += int(4 * fScale);
		if (ch == 'J')
			nX += int(4 * fScale);
		if (ch == 'M')
			nX += int(4 * fScale);
		if (ch == 'H')
			nX += int(4 * fScale);
		if (ch == 'R')
			nX += int(4 * fScale);
		if (ch == 'B')
			nX += int(4 * fScale);
		if (ch == 'N')
			nX += int(4 * fScale);

		// Move the x for the next character
		nX += (int)(m_nCharWidth * fScale);
	}
}


/*************************************************/
// CellAlgorithm
//	- return the source rect in the image for the
//	  symbol with the given id (0-based index)
SGD::Rectangle BitmapFont::CellAlgorithm( int id ) const
{
	SGD::Rectangle rChar = { };

	rChar.left		= (float)(id %  m_nNumCols) * m_nCharWidth;
	rChar.top		= (float)(id / m_nNumCols) * m_nCharHeight;

	rChar.right		= rChar.left + m_nCharWidth;
	rChar.bottom	= rChar.top  + m_nCharHeight;

	return rChar;
}
